package com.zhongen.oa.datascope;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhongen.admin.api.entity.SysDept;
import com.zhongen.admin.api.entity.SysRole;
import com.zhongen.admin.api.entity.SysUser;
import com.zhongen.admin.service.SysDeptService;
import com.zhongen.admin.service.SysUserService;
import com.zhongen.common.core.datascope.DataScopeTypeEnum;
import com.zhongen.common.core.datascope.UserDataScope;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class SampleDataScopeProcessor implements DataScopeProcessor {

	private final SysDeptService deptService;

	private final SysUserService userService;

	/**
	 * 合并角色的数据权限类型，排除相同的权限后，大的权限覆盖小的
	 * @return UserDataScope 合并后的权限
	 */
	@Override
	public UserDataScope mergeScopeType(SysUser user, List<SysRole> roles) {
		UserDataScope userDataScope = new UserDataScope();
		Set<Long> scopeUserIds = userDataScope.getScopeUserIds();
		Set<Long> scopeOrganizationId = userDataScope.getScopeDeptIds();

		// 任何用户都应该可以看到自己的数据
		Long userId = user.getUserId();
		scopeUserIds.add(userId);

		if (CollUtil.isEmpty(roles)) {
			return userDataScope;
		}

		// 根据角色的权限返回进行分组
		Map<Long, List<SysRole>> map = roles.stream().collect(Collectors.groupingBy(SysRole::getScopeType));
		// 如果有全部权限，直接返回
		if (map.containsKey(DataScopeTypeEnum.ALL.getType())) {
			userDataScope.setAllScope(true);
			return userDataScope;
		}

		// 如果有本级及子级，删除其包含的几类数据权限
		boolean hasLevelChildLevel = map.containsKey(DataScopeTypeEnum.LEVEL_CHILD_LEVEL.getType());
		if (hasLevelChildLevel) {
			map.remove(DataScopeTypeEnum.SELF.getType());
			map.remove(DataScopeTypeEnum.SELF_CHILD_LEVEL.getType());
			map.remove(DataScopeTypeEnum.LEVEL.getType());
		}

		// 是否有本人及子级权限
		boolean hasSelfChildLevel = map.containsKey(DataScopeTypeEnum.SELF_CHILD_LEVEL.getType());
		// 是否有本级权限
		boolean hasLevel = map.containsKey(DataScopeTypeEnum.LEVEL.getType());
		if (hasSelfChildLevel || hasLevel) {
			// 如果有本人及子级或者本级，都删除本人的数据权限
			map.remove(DataScopeTypeEnum.SELF.getType());
			// 如果同时拥有，则等于本级及子级权限
			if (hasSelfChildLevel && hasLevel) {
				map.remove(DataScopeTypeEnum.SELF_CHILD_LEVEL.getType());
				map.remove(DataScopeTypeEnum.LEVEL.getType());
				map.put(DataScopeTypeEnum.LEVEL_CHILD_LEVEL.getType(), new ArrayList<>());
			}
		}

		// 这时如果仅仅只能看个人的，直接返回
		if (map.size() == 1 && map.containsKey(DataScopeTypeEnum.SELF.getType())) {
			userDataScope.setOnlySelf(true);
			return userDataScope;
		}

		// 如果有 本级及子级 或者 本级，都把自己的 organizationId 加进去
		Long organizationId = user.getDeptId();
		if (hasLevelChildLevel || hasLevel) {
			scopeOrganizationId.add(organizationId);
		}
		// 如果有 本级及子级 或者 本人及子级，都把下级组织的 organizationId 加进去
		if (hasLevelChildLevel || hasSelfChildLevel) {
			List<SysDept> childOrganizations = deptService.listDescendant(organizationId);
			if (CollUtil.isNotEmpty(childOrganizations)) {
				List<Long> organizationIds = childOrganizations.stream().map(SysDept::getDeptId).toList();
				scopeOrganizationId.addAll(organizationIds);
			}
		}

		// 自定义部门
		List<SysRole> sysRoles = map.get(DataScopeTypeEnum.CUSTOM.getType());
		if (CollUtil.isNotEmpty(sysRoles)) {
			Set<Long> customDeptIds = sysRoles.stream()
				.map(SysRole::getScopeResources)
				.filter(Objects::nonNull)
				.flatMap(x -> Arrays.stream(x.split(",")))
				.map(Long::parseLong)
				.collect(Collectors.toSet());
			scopeOrganizationId.addAll(customDeptIds);
		}

		// 把部门对应的用户id都放入集合中
		if (CollUtil.isNotEmpty(scopeOrganizationId)) {
			List<SysUser> sysUserList = userService.list(Wrappers.<SysUser>query().in("dept_id", scopeOrganizationId));
			if (CollUtil.isNotEmpty(sysUserList)) {
				List<Long> userIds = sysUserList.stream().map(SysUser::getUserId).toList();
				scopeUserIds.addAll(userIds);
			}
		}

		return userDataScope;
	}

}
